var fs = require('fs'),
    http = require('http'),
    PublicConst = require("./Const"),
    PublicEnum = require("./Enum"),
    socket = require('./Socket'),
    entityCollection = require('./EntityCollection');

exports.checkUser = function(user){
    if(user == undefined){
        return false;
    }

    return true;
};

exports.getErrMsgByRecord = function(entityName, record, msg){
    var newMsg = "";    //"表名：" + entityName + "\n";
    if(record.Name != undefined){
        newMsg += "名称：" + record.Name + "\n";
    }
    if(record.Code != undefined){
        newMsg += "编码：" + record.Code + "\n";
    }
    if(newMsg === ""){
        newMsg += "ID：" + record._id + "\n";
    }

    newMsg += "信息：\n  " + msg;
    return newMsg;
};

exports.authorizedCheck = function(user, res){
    if(!exports.checkUser(user)){
        var newErr = new Error();
        newErr.leval = 0;
        newErr.title = '用户验证失败';
        newErr.message = '登录超时，请重新登录';
        res.status(400).send(newErr);
        res.ends();
    }
};

exports.responseHandler = function(res) {
    return function (err, data) {
        exports.responseFun(res, err, data);
    };
};
exports.responseFun = function(res, err, data) {
    if (err) {
        exports.errorLog(err.title, err.message);
        res.json({ Error: err });
        // res.status(400).send({
        //     message: "错误信息"
        // });

    } else {
        res.json({ Data: data });
    }
    res.end();
};

//将条件格式化处理
//比如：查询配送记录，条件：InputWork.Name = "aa"，会先将 InputWork.Name 转换为 Work.Name，
//因为没有InputWork实体，通过Schema找到InputWork对应的是Work字段，然后格式化正则表达式
exports.formatCondition = function(entityClass, condition, resultHandel){
    try{
        var newCondition = {};
        //单个字段里面如果包含关联实体属性，将其条件转换为本实体字段对应的id集合
        var getFieldCondition = function(conditionFiled, fieldName, fieldCondition, completeFun){
            if(fieldName.indexOf(".") > -1){
                var fileds = fieldName.split(".");
                var entityName = fileds[fileds.length - 2];
                var lastFiledName = fileds[fileds.length - 1];;
                var childCondition = {};
                childCondition[lastFiledName] = fieldCondition;

                var entity = entityCollection.getEntity(entityName);
                if(entity != null && entity != undefined){
                    entity.Entity.find(childCondition).exec(function(err, records) {
                        if (err) {
                            var newErr = new Error();
                            newErr.leval = 5;
                            newErr.title = '【' + entityName + '】' + '查找错误';
                            newErr.message = err.message;
                            if (completeFun != null && completeFun != undefined) {
                                completeFun(newErr);
                            }
                        }
                        else {
                            var ids = [];
                            for (var j = 0; j < records.length; j++) {
                                ids.push(records[j]._id);
                            }

                            getFieldCondition(conditionFiled, fieldName.substring(0, fieldName.lastIndexOf(".")), {$in: ids}, completeFun);
                        }
                    });
                }
                else{
                    completeFun({
                        leval: 5,
                        title: '数据库条件错误',
                        message: "没有找到" + entityName + "所对应的实体"
                    });
                }
            }
            else{
                completeFun(null, conditionFiled, fieldCondition);
            }
        };
        //将条件进行格式化，将传过来的正则表达式字符串转换为正则表达式
        var regexCondition = function(condition){
            for(var p in condition){
                if(condition[p] != null) {
                    if (condition[p].constructor == String) {
                        if (condition[p].search(/^\/.*\/$/) > -1) {
                            condition[p] = new RegExp(condition[p].substring(1, condition[p].length - 1));
                        }
                    }
                    else if (condition[p].constructor == Array) {
                        for(var i=0; i<condition[p].length; i++){
                            condition[p][i] = regexCondition(condition[p][i]);
                        }
                    }
                    else if (condition[p].constructor == Object) {
                        condition[p] = regexCondition(condition[p]);
                    }
                }
            }

            return condition;
        };

        var conditionLengths = 0;
        for(var p in condition) {
            conditionLengths++;
        }
        if(conditionLengths == 0){
            resultHandel(null, {});
        }
        else {
            condition = regexCondition(condition);
            for (var p in condition) {
                //因为有的字段名称不一定是实体名称，所以要先将这些转换成对应的实体名称
                var conditionFiled = fieldAttribute = p;
                if(fieldAttribute.indexOf(".") > -1){
                    var fieldAttributes = fieldAttribute.split(".");
                    conditionFiled = fieldAttributes[0];
                    for(var i=0; i<fieldAttributes.length - 1; i++){
                        var entityName;
                        if(i == 0){
                            entityName = entityClass.Entity.schema.paths[fieldAttributes[0]].options["ref"];
                        }
                        else{
                            var fieldEntity = entityCollection.getEntity(fieldAttributes[i-1]);
                            if (fieldEntity == null || fieldEntity == undefined) {
                                resultHandel({
                                    level: 5,
                                    title: "查询条件错误",
                                    message: fieldAttributes[i-1] + "不是实体字段，没有子属性" + fieldAttributes[i]
                                });
                                return;
                            };
                            entityName = fieldEntity.Entity.schema.paths[fieldAttributes[i]].options["ref"];
                        }

                        if(entityName != null && entityName != undefined){
                            fieldAttributes[i] = entityName;
                        }
                    }
                    fieldAttribute = fieldAttributes.toString().replace(/,/g, ".");
                }

                getFieldCondition(conditionFiled, fieldAttribute, condition[p], function (err, fieldName, fieldCondition) {
                    if (err) {
                        if (resultHandel != null && resultHandel != undefined) {
                            resultHandel(err);
                            return;
                        }
                    }
                    else {
                        conditionLengths--;
                        newCondition[fieldName] = fieldCondition;
                        if (conditionLengths == 0) {
                            if (resultHandel != null && resultHandel != undefined) {
                                resultHandel(null, newCondition);
                                return;
                            }
                        }
                    }
                });
            }
        }
    }
    catch(e){
        resultHandel({
            leval: 5,
            title: '数据库条件错误',
            message: "详细信息：" + e.message + "\n" + "条件：" + condition.toString()
        });
    }
};

//记录错误日志
exports.errorLog = function(title, msg, strUser){
    var strMsg;
    var nowDate = new Date();
    strMsg = nowDate.getFullYear() + '-' + (nowDate.getMonth() + 1) + '-' + nowDate.getDate() + ' ' + nowDate.getHours() + ":" + nowDate.getMinutes() + ":" + nowDate.getSeconds();
    if(strUser != undefined && strUser.trim() != ''){
        strMsg += ' 【' + strUser + '】';
    }
    strMsg += '\r\n标题：' + title + '\r\n' + '错误信息：' + msg + '\r\n\r\n';

    var isExist = fs.existsSync('./logs/error.log');
    if(isExist){
        var errorLogfile = fs.createWriteStream('./logs/error.log', {flags: 'a'});    //打开错误日志文件
        errorLogfile.write(strMsg);
    }
};

//记录访问日志
exports.accessLog = function(title, msg, strUser){
    var strMsg;
    var nowDate = new Date();
    strMsg = nowDate.getFullYear() + '-' + (nowDate.getMonth() + 1) + '-' + nowDate.getDate() + ' ' + nowDate.getHours() + ":" + nowDate.getMinutes() + ":" + nowDate.getSeconds();
    if(strUser != undefined && strUser.trim() != ''){
        strMsg += ' 【' + strUser + '】';
    }
    strMsg += '标题：' + title + '\r\n' + '错误信息：' + msg + '\r\n\r\n';

    var isExist = fs.existsSync('./logs/access.log');
    if(isExist){
        var accessLogfile = fs.createWriteStream('./logs/access.log', {flags: 'a'});    //打开访问日志文件
        accessLogfile.write(strMsg);
    }
};

//下载文件
exports.downloadFile = function(serverPath, downloadFileName, fileName, deleteFileName, socketId, returnHandle){
    serverPath = serverPath.replace(/\\/g, "/");
    //去掉http头
    if(serverPath.indexOf('//') > -1){
        serverPath = serverPath.split('//')[1];
    }
    if(fileName == undefined || fileName == null || fileName.trim() == ''){
        fileName = downloadFileName;
    }
    
    var serverAddress = serverPath.substring(0, serverPath.indexOf('/'));   //文件服务器IP及Port
    var serverApiPath = serverPath.substring(serverPath.indexOf('/'), serverPath.length);     //文件服务器Api
    var serverHostName = serverAddress; //文件服务器地址
    var serverPort = 80;    //文件服务器端口
    if(serverAddress.indexOf(':') > 0){
        serverHostName = serverAddress.split(':')[0];
        serverPort = parseInt(serverAddress.split(':')[1]);
    }

    var parameter = {
        FileName: fileName
    };
    parameter = JSON.stringify(parameter);

    var options = {
         hostname: serverHostName,
         port: serverPort,
         path: serverApiPath,
         method: 'POST',
         headers: {
             "Content-Type": 'application/json',
             "Content-Length": parameter.length
        }
    };

    var fileFullPath = PublicConst.FilePath + fileName;

    //创建写入流
    var fileWriteStream = fs.createWriteStream(fileFullPath + '.temp');
    var httpRequest = http.request(options, function (httpResponse) {
        httpResponse.on('data', function(data){
            fileWriteStream.write(data);

            if(socketId != null && socketId != undefined && socketId.trim() != ""){
                socket.emitBySocketId(socketId, downloadFileName + "_DownloadSize", data.length);
            }
        });
        httpResponse.on('end', function(){
            fileWriteStream.end();
            if(deleteFileName != null && deleteFileName != undefined && deleteFileName.trim() != ''){
                //删除已有文件
                exports.fileDeleteSync(PublicConst.FilePath + deleteFileName);
            }
            //重命名
            exports.fileRenameSync(fileFullPath + '.temp', fileFullPath);
            if(socketId != null && socketId != undefined && socketId.trim() != ""){
                socket.emitBySocketId(socketId, downloadFileName + "_DownloadComplete", true);
            }
            returnHandle(null, {FileName: fileName});
        });
    });

    httpRequest.write(parameter);

    httpRequest.on('error', function (err) {
        returnHandle(err);
    });
    httpRequest.end();
};

//文件重命名
//异步
exports.fileRename = function(oldPath, newPath, completeFun){
    fs.exists(path, function(isExists) {
        if(isExists) {
            fs.rename(oldPath, newPath, function (err) {
                if (completeFun) {
                    completeFun(err);
                }
            });
        }
        else{
            var newErr = new Error();
            newErr.leval = 0;
            newErr.title = '重命名失败';
            newErr.message = '文件不存在';

            completeFun(newErr);
        }
    });
};
//同步
exports.fileRenameSync = function(oldPath, newPath){
    try{
        fs.renameSync(oldPath, newPath);
        return true;
    }
    catch(e){
        return false;
    }
};

//删除文件
//异步
exports.fileDelete = function(path, completeFun){
    fs.exists(path, function(isExists){ 
        if(isExists){ 
            //删除文件
            fs.unlink(path, function(err){
                if(completeFun){
                    completeFun(err);
                }
            });
        }
    });
};
//同步
exports.fileDeleteSync = function(path){
    if(fs.existsSync(path)){
        try{
            fs.unlinkSync(path);
            return true;
        }
        catch(e){
            return false;
        }
    }
    else{
        return false;
    }
};

//获取系统参数值
exports.getSysParameterValue = function(code, completeFun){
    var entity = entityCollection.getEntity("Parameter");
    entity.findOne({Code: code}, null, function(err, record){
        if(err){
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '系统查询错误';
            newErr.message = '通过编码查询系统参数失败，请检查查询条件';
            completeFun(newErr);
        }
        else {
            if(record != null){
                var value;
                if(record.Type == PublicEnum.ControlType.TextBox){
                    value = record.Value;
                }
                else if(record.Type == PublicEnum.ControlType.CheckBox){
                    if(record.Value == 'true'){
                        value = true;
                    }
                    else{
                        value = false;
                    }
                }
                else if(record.Type == PublicEnum.ControlType.NumberBox){
                    value = parseFloat(record.Value);
                }
                else if(record.Type == PublicEnum.ControlType.PercentBox){
                    value = parseFloat(record.Value);
                }
                else if(record.Type == PublicEnum.ControlType.DropDownList){
                    value = parseInt(record.Value);
                }
                else if(record.Type == PublicEnum.ControlType.Refer){
                    value = {
                        Key: record.Key,
                        Value: record.Value,
                        Text: record.Text
                    };
                }
                else if(record.Type == PublicEnum.ControlType.Calendar){
                    if(record.CalendarType == PublicEnum.DateTimeFormat.Date){
                        var date = new Date(record.Value);
                        value = new Date(date.getFullYear(), date.getMonth(), date.getDate());
                    }
                    else{
                        value = new Date(record.Value);
                    }
                }
                completeFun(null, value);
            }
            else{
                completeFun(null, null);
            }
        }
    });
};
